インフラエンジニアのためのCodeBuild,CodePipelineで覚えるユニットテスト
先日インフラエンジニアのためのCodeCommitで覚えるユニットテストを公開し、ローカルでユニットテストをして、CodeCommitにプルリクエストするまでの流れをご紹介しました。
今回はCodeBuildとCodePipelineを使って、ユニットテストを自動実行する流れを紹介します。 devブランチへのpushを検知して、ユニットテストを実行します。
手動でユニットテストを実行
自動で実行する前に、手動でユニットテストを実行できるようにします。 足し算、引き算が出来るcalc.pyとテストファイル(test_calc.py)を配置し、CodeCommitにPushします。 詳しくはブログをご覧ください。
$ tree ./ ./ ├── calc.py └── tests └── test_calc.py
calc.py
足し算関数(plus)と、引き算関数(minus)を持ちます。
def plus(x,y): return x + y def minus(x,y): return x - y
test_calc.py
足し算関数と、引き算関数をテストします。 足し算関数に3,5を与えて、3+5=8になるかを確認します。 引き算関数には10,3を与えて、10-3=7になるかを確認します。
import unittest import calc class TestCalc(unittest.TestCase): def test_plus(self): self.assertEqual(calc.plus(3,5), 8) def test_minus(self): self.assertEqual(calc.minus(10,3), 7)
ユニットテストの実行
テストを実行すると2つの項目が実行され、"OK"になります。
$ python3 -m unittest tests.test_calc .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK $
CodeBuildでのユニットテスト実行
ビルドスペックファイルを配置し、CodeBuildプロジェクトを作成します。
devブランチの作成
開発用のdevブランチを作成します。
$ git checkout -b dev Switched to a new branch 'dev' $ git branch * dev master $
ビルドスペックファイルの配置
ビルドスペックファイル(buildspec.yml)をソースディレクトリのルートに配置します。
$ tree ./ ./ ├── buildspec.yml ├── calc.py └── tests └── test_calc.py 1 directory, 3 files $
ビルドスペックのサンプルはユーザーガイドに記載されています。
phases>build>commandsにユニットテストのコマンドpython3 -m unittest tests.test_calc
を記載します。
artifactsでは、成果物(アーティファクト)を指定します。
version: 0.2 phases: build: commands: - echo Build started on `date` - echo Compiling the Python code... - python3 -m unittest tests.test_calc post_build: commands: - echo Build completed on `date` artifacts: files: - calc.py
オリジンへのpush
devブランチをオリジンにpushします。
git add ./* git commit -m "add buildspec.yml" git push origin dev
CodeBuildプロジェクトの作成
CodeBuildプロジェクトを作成します。 プロジェクト「blog-python-unittest」を作成し、LinuxのPython 3.6.5環境を指定しました。 ビルド仕様には、「ソースコードのルートディレクトリの buildspec.yml を使用」を指定します。先ほど作成したYAMLの通りにビルドするということです。
作成したプロジェクトを選択し、「ビルドの開始」を選択します。
devブランチを選択します。
ユニットテストを実行すると、フェーズごとの状態が表示されます。 今回は全て成功しました。 ビルドログには、ユニットテストの結果が表示されます。
CodePipelineで自動実行
CodePipelineは、変更が発生した時にCloudWatchイベントを使って、自動的にビルドを実行します。 SourceステージにCodeCommit、BuildステージにCodeBuildを指定しました。
かけ算機能の追加
かけ算機能を追加し、テストを自動実行します。
calc.py
times関数を追加します。 2つの引数をかけ算して、結果を返します。 retrunのスペルが誤っていますが、そのままにしておきます。
def plus(x,y): return x + y def minus(x,y): return x - y def times(x,y): retrun x * y
test_calc.py
かけ算関数をテストします。4×8=32になるかを確認します。
import unittest import calc class TestCalc(unittest.TestCase): def test_plus(self): self.assertEqual(calc.plus(3,5), 8) def test_minus(self): self.assertEqual(calc.minus(10,3), 7) def test_times(self): self.assertEqual(calc.times(4,8), 32)
かけ算関数のpush
CodeCommitのdevブランチにpushします。
git add ./* git commit -m "add times function" git push origin dev
pushすると、ユニットテストが自動で実行されます。 returnのスペルが誤っているので、失敗しました。 詳細リンクを選択すると、CodeBuildコンソールに飛びます。
CodeBuildコンソールでは、calc.pyの8行目に文法エラーがあることがわかります。
ユニットテストのステータスコードが"1"のため、BUILDフェーズが失敗したことがわかります。「Error while executing command: python3 -m unittest tests.test_calc. Reason: exit status 1」
コードの修正とpush
「retrun」を正しく「return」に変更して、pushします。 自動でユニットテストが行われ、グリーン(成功)しました。
さいごに
CodeBuildとCodePipelineを使って、devブランチへのpushを検知し、ユニットテストを自動実行しました。 サービスやユニットテストの概要を掴むお手伝いができたのであれば、幸いです。